import React, { Component } from 'react';

const ImageLoaderWrapper = (ComponentClass) => {
    return class ImageLoader extends Component {
        constructor(props){
            super(props);

            this.state = {
                src: props.src,
                isLoading: false,
                isError: false,
                img: null
            };

            this.load = this._load();
        }
        componentDidMount() {
            const { src } = this.state;

            if(src){
                this.setState({
                    src
                }, () => {
                    this.load();
                })
            } else {
                this.setState({
                    isError: true
                })
                console.log('没配置图片地址');
            }
        }
        componentWillUnmount() {
            this.stop();
        }
        componentWillReceiveProps(nextProp) {
            const { props } = this;
            if (props.src !== nextProp.src) {
                this.setState({
                    src: nextProp.src
                }, () => {
                    this.load();
                })
            }
        }
        stop(){
            clearInterval(this.intervalId);
            this.intervalId = null;
        }
        _load(){
            let index = 0,
                list = [];

            const { props } = this;
            return (params = {}) => {
                const { src } = this.state;
                let onready, width, height, newWidth, newHeight,
                    img = new Image(),
                    eventObj = {};

                eventObj.index = ++index;
                img.src = eventObj.src = src;
                eventObj.img = img;
                this.setState({
                    isLoading: true
                });
                props.onLoadStart && props.onLoadStart(Object.assign({eventObj, params}));

                if (img.complete && img.width){
                    setTimeout(() => {

                        this.setState({
                            isLoading: false,
                            isError: false,
                            img
                        });
                        props.onReady && props.onReady(Object.assign({eventObj, params}));
                        props.onLoad && props.onLoad(Object.assign({eventObj, params}));

                    },1);
                    return;
                }
                width = img.width;
                height = img.height;

                let imgfix = img;
                imgfix.onerror = () => {
                    onready.end = true;
                    this.setState({
                        isLoading: false,
                        isError: true,
                        img: null
                    });
                    console.log('加载图片失败');
                    img = img.onload = img.onerror = null;

                    props.onError && props.onError(Object.assign({eventObj, params}));
                }

                onready = () => {
                    newWidth = img.width;
                    newHeight = img.height;
                    if(newWidth !== width || newHeight !== height || newWidth * newHeight > 1024){
                        this.setState({
                            isLoading: false,
                            isError: false,
                            img
                        });
                        props.onReady && props.onReady(Object.assign({eventObj, params}));

                        onready.end = true;
                    }
                }

                onready();
                img.onload = () => {
                    !onready.end && onready();
                    img = img.onload = img.onerror = null;
                    this.setState({
                        isLoading: false,
                        isError: false,
                        img
                    });
                    props.load && props.load(Object.assign({eventObj, params}));
                }

                if (!onready.end){
                    list.push(onready);
                    if(this.intervalId === null){
                        this.intervalId = setInterval(() => {
                            var i = 0;
                            for (; i < list.length; i++){
                                list[i].end ? list.splice(i--, 1) : list[i]();
                            }
                            !list.length && this.stop();
                        }, 40);
                    }
                }
            }
        }
        render(){
            const { img, isLoading } = this.state;
            return <ComponentClass {...this.props} isLoading={isLoading} img={img} />
        }
    }
}

export default ImageLoaderWrapper;